<?php
require_once 'config.php';
require_once 'facepp_sdk.php';
//人脸识别
require_once 'baiduMapClient.php';
require_once 'Utils.php';
#require_once "jssdk.php";

//整体入口
$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET['echostr'])) {
	$wechatObj -> responseMsg();
} else {
	$wechatObj -> valid();
}

class wechatCallbackapiTest {
	/**
	 * @description 验证签名
	 */
	public function valid() {
		$echoStr = $_GET["echostr"];
		$signature = $_GET["signature"];
		$timestamp = $_GET["timestamp"];
		$nonce = $_GET["nonce"];
		$token = TOKEN;
		$tmpArr = array($token, $timestamp, $nonce);
		sort($tmpArr);
		$tmpStr = implode($tmpArr);
		$tmpStr = sha1($tmpStr);
		if ($tmpStr == $signature) {
			echo $echoStr;
			exit ;
		}
	}

	/**
	 * @description 响应消息
	 */
	public function responseMsg() {
		$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
		if (!empty($postStr)) {
			#$this -> logger("R " . $postStr);
			$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
			$RX_TYPE = trim($postObj -> MsgType);
			//获取事件类型
			$this -> logger(" Revice rx_type:" . $RX_TYPE);
			//消息类型分离
			switch ($RX_TYPE) {
				case "event" :
					//事件
					$result = $this -> receiveEvent($postObj);
					break;
				case "text" :
					//文本
					$result = $this -> receiveText($postObj);
					break;
				case "image" :
					//图片,先识别图片，能识别人信息就先出信息，再添加图片文件信息
					$result = $this -> receiveImage($postObj);
					break;
				case "location" :
					//地址
					$result = $this -> receiveLocation($postObj);
					break;
				case "voice" :
					//声音
					$result = $this -> receiveVoice($postObj);
					break;
				case "video" :
					//视频
					$result = $this -> receiveVideo($postObj);
					break;
				case "link" :
					//链接
					$result = $this -> receiveLink($postObj);
					break;
				default :
					//未知情况
					$result = "unknown msg type: " . $RX_TYPE;
					break;
			}
			#$this -> logger("T " . $result);
			echo $result;
		} else {
			echo "";
			exit ;
		}
	}

	/**
	 * @description 接收事件消息
	 * @param {$object} 事件对象
	 */
	private function receiveEvent($object) {
		$content = "";
		switch ($object->Event) {
			case "subscribe" :
				//关注事件
				$content = "欢迎关注丰华挚友 ";
				$content .= (!empty($object -> EventKey)) ? ("\n来自二维码场景 " . str_replace("qrscene_", "", $object -> EventKey)) : "";
				break;
			case "unsubscribe" :
				//取消关注事件
				$content = "取消关注";
				break;
			case "SCAN" :
				//扫描事件
				$content = "扫描场景 " . $object -> EventKey;
				break;
			case "CLICK" :
				//单击事件
				switch ($object->EventKey) {
					case "COMPANY" :
						$content = array();
						$content[] = array("Title" => "多图文1标题", "Description" => "", "PicUrl" => "http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" => "http://m.cnblogs.com/?u=txw1958");
						break;
					default :
						$content = "点击菜单：" . $object -> EventKey;
						break;
				}
				break;
			case "LOCATION" :
				$content = "上传位置：纬度 " . $object -> Latitude . ";经度 " . $object -> Longitude;
				break;
			case "VIEW" :
				$content = "跳转链接 " . $object -> EventKey;
				break;
			case "MASSSENDJOBFINISH" :
				$content = "消息ID：" . $object -> MsgID . "，结果：" . $object -> Status . "，粉丝数：" . $object -> TotalCount . "，过滤：" . $object -> FilterCount . "，发送成功：" . $object -> SentCount . "，发送失败：" . $object -> ErrorCount;
				break;
			default :
				$content = "receive a new event: " . $object -> Event;
				break;
		}
		if (is_array($content)) {
			if (isset($content[0])) {
				$result = $this -> transmitNews($object, $content);
			} else if (isset($content['MusicUrl'])) {
				$result = $this -> transmitMusic($object, $content);
			}
		} else {
			$result = $this -> transmitText($object, $content);
		}

		return $result;
	}

	/**
	 * @description 接收文本消息
	 * @param {$object} 事件对象
	 */
	private function receiveText($object) {
		$keyword = trim($object -> Content);
		$this -> logger("keyword:" . $keyword . ",code:" . $object);
		//多客服人工回复模式
		if (strstr($keyword, "hello") || strstr($keyword, "Hello") || strstr($keyword, "在吗")) {
			$result = $this -> transmitService($object);
		}
		//获取位置信息
		else if (strpos($keyword, "酒店") !== false || strpos($keyword, "医院") !== false || strpos($keyword, "银行") !== false) {
			$radius = 5000;
			$TitleArray = array();
			$TitleArray[] = array("Title" => "附近的【" . $keyword . "】如下：", "Description" => "", "PicUrl" => "http://discuz.comli.com/weixin/weather/icon/scenery.jpg", "Url" => "");
			$searchArray = catchEntitiesFromLocation($keyword, 30.6547120000, 104.0712190000, $radius);
			if (count($searchArray) == 0) {
				$content = "附近没有" . $keyword;
				$result = $this -> transmitText($object, $content);
			} else {
				$result = $this -> transmitNews($object, array_merge_recursive($TitleArray, $searchArray));
				$this -> logger("searchArray:" . $searchArray);
			}
		}
		//自动回复模式
		else {
			if (strstr($keyword, "文本")) {
				$content = "这是个文本消息";
			} else if (strstr($keyword, "单图文")) {
				$content = array();
				$content[] = array("Title" => "单图文标题", "Description" => "单图文内容", "PicUrl" => "http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" => "http://m.cnblogs.com/?u=txw1958");
			} else if (strstr($keyword, "图文") || strstr($keyword, "多图文")) {
				$content = array();
				$content[] = array("Title" => "多图文1标题", "Description" => "", "PicUrl" => "http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" => "http://m.cnblogs.com/?u=txw1958");
				$content[] = array("Title" => "多图文2标题", "Description" => "", "PicUrl" => "http://d.hiphotos.bdimg.com/wisegame/pic/item/f3529822720e0cf3ac9f1ada0846f21fbe09aaa3.jpg", "Url" => "http://m.cnblogs.com/?u=txw1958");
				$content[] = array("Title" => "多图文3标题", "Description" => "", "PicUrl" => "http://g.hiphotos.bdimg.com/wisegame/pic/item/18cb0a46f21fbe090d338acc6a600c338644adfd.jpg", "Url" => "http://m.cnblogs.com/?u=txw1958");
			} else if (strstr($keyword, "音乐")) {
				$content = array();
				$music = Utils::get_music_json();//从文件夹resource/music下获取文件列表后保存到music.json文件中,然后直接获取json数据
				//获取歌曲JSON对象数组
				$mItem = $music[rand(0, count($music) - 1)];
				$mItem = is_object($mItem) ? get_object_vars($mItem) : $mItem;
				$content = array("Title" => urldecode($mItem['Title']), "Description" => urldecode($mItem['Description']), "MusicUrl" => urldecode($mItem['MusicUrl']), "HQMusicUrl" => urldecode($mItem['MusicUrl']));
			} else {
				$content = date("Y-m-d H:i:s", time()) . "\n欢迎光临		丰华挚友";
			}

			if (is_array($content)) {
				if (isset($content[0]['PicUrl'])) {
					$result = $this -> transmitNews($object, $content);
				} else if (isset($content['MusicUrl'])) {
					$result = $this -> transmitMusic($object, $content);
				}
			} else {
				$result = $this -> transmitText($object, $content);
			}
		}
		return $result;
	}

	//接收图片消息
	private function receiveImage($object) {
		$content = array("MediaId" => $object -> MediaId);
		#$mediaid = $content['MediaId'];
		$pic = array("PicUrl" => $object -> PicUrl);
		$picurl = $pic['PicUrl'];
		/*$url="http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=$access_token&media_id=$mediaid";
		 $fileInfo=downloadWeixinFile($url);
		 $filename="down_image.jpg";
		 saveWeixinFile($filename, $fileInfo["body"]);*/

		$facepp = new Facepp();

		$params = array('url' => $picurl);
		#$params['attribute'] = 'gender,age,race,smiling,glass,pose';
		$response = $facepp -> execute('/detection/detect', $params);
		/*$params=array('url'=>'http://www.faceplusplus.com.cn/wp-content/themes/faceplusplus/assets/img/demo/1.jpg');
		 $response = $facepp->execute('/detection/detect',$params);*/
		$this -> logger(" picurl:" . $picurl . ",http_code:" . $response['http_code']);
		if ($response['http_code'] == 200) {
			#json decode
			$data = json_decode($response['body'], 1);
			/*#get face landmark
			 foreach ($data['face'] as $face) {
			 $response = $facepp->execute('/detection/landmark',array('face_id'=>$face['face_id']));
			 print_r($response);
			 }
			 #create person
			 $response = $facepp->execute('/person/create',array('person_name'=>'unique_person_name'));
			 print_r($response);

			 #delete person
			 $response = $facepp->execute('/person/delete',array('person_name'=>'unique_person_name'));
			 print_r($response);*/

			$d = $data['face'][0]['attribute'];

			$itemTpl = "年龄:%s,误差：%s\n性别为:%s,置信度为：%s\n种族为亚洲:%s\n微笑度:%s\n";
			$rs = sprintf($itemTpl, $d['age']['value'], $d['age']['range'], $d['gender']['value'], $d['gender']['confidence'], $d['race']['value'], $d['smiling']['value']);

			$result = $this -> transmitText($object, $rs . "	by	丰华挚友");
		} else {
			$result = $this -> transmitText($object, "哎呀，这厮有诈!");
			$result = $result . ($this -> transmitImage($object, $content));
		}
		return $result;
	}

	//接收位置消息
	private function receiveLocation($object) {
		$content = "你发送的是位置，纬度为：" . $object -> Location_X . "；经度为：" . $object -> Location_Y . "；缩放级别为：" . $object -> Scale . "；位置为：" . $object -> Label;
		$result = $this -> transmitText($object, $content);
		return $result;
	}

	//接收语音消息
	private function receiveVoice($object) {
		if (isset($object -> Recognition) && !empty($object -> Recognition)) {
			$content = "你刚才说的是：" . $object -> Recognition;
			$result = $this -> transmitText($object, $content);
		} else {
			$content = array("MediaId" => $object -> MediaId);
			$result = $this -> transmitVoice($object, $content);
		}

		return $result;
	}

	//接收视频消息
	private function receiveVideo($object) {
		$content = array("MediaId" => $object -> MediaId, "ThumbMediaId" => $object -> ThumbMediaId, "Title" => "", "Description" => "");
		$result = $this -> transmitVideo($object, $content);
		return $result;
	}

	//接收链接消息
	private function receiveLink($object) {
		$content = "你发送的是链接，标题为：" . $object -> Title . "；内容为：" . $object -> Description . "；链接地址为：" . $object -> Url;
		$result = $this -> transmitText($object, $content);
		return $result;
	}

	//回复文本消息
	private function transmitText($object, $content) {
		$xmlTpl = "<xml>
					<ToUserName><![CDATA[%s]]></ToUserName>
					<FromUserName><![CDATA[%s]]></FromUserName>
					<CreateTime>%s</CreateTime>
					<MsgType><![CDATA[text]]></MsgType>
					<Content><![CDATA[%s]]></Content>
					</xml>";
		$result = sprintf($xmlTpl, $object -> FromUserName, $object -> ToUserName, time(), $content);
		return $result;
	}

	//回复图片消息
	private function transmitImage($object, $imageArray) {
		$itemTpl = "<Image>
				    <MediaId><![CDATA[%s]]></MediaId>
				</Image>";

		$item_str = sprintf($itemTpl, $imageArray['MediaId']);

		$xmlTpl = "<xml>
				<ToUserName><![CDATA[%s]]></ToUserName>
				<FromUserName><![CDATA[%s]]></FromUserName>
				<CreateTime>%s</CreateTime>
				<MsgType><![CDATA[image]]></MsgType>
				$item_str
				</xml>";

		$result = sprintf($xmlTpl, $object -> FromUserName, $object -> ToUserName, time());
		return $result;
	}

	//回复语音消息
	private function transmitVoice($object, $voiceArray) {
		$itemTpl = "<Voice>
		    <MediaId><![CDATA[%s]]></MediaId>
		</Voice>";

		$item_str = sprintf($itemTpl, $voiceArray['MediaId']);

		$xmlTpl = "<xml>
				<ToUserName><![CDATA[%s]]></ToUserName>
				<FromUserName><![CDATA[%s]]></FromUserName>
				<CreateTime>%s</CreateTime>
				<MsgType><![CDATA[voice]]></MsgType>
				$item_str
				</xml>";

		$result = sprintf($xmlTpl, $object -> FromUserName, $object -> ToUserName, time());
		return $result;
	}

	//回复视频消息
	private function transmitVideo($object, $videoArray) {
		$itemTpl = "<Video>
			    <MediaId><![CDATA[%s]]></MediaId>
			    <ThumbMediaId><![CDATA[%s]]></ThumbMediaId>
			    <Title><![CDATA[%s]]></Title>
			    <Description><![CDATA[%s]]></Description>
			</Video>";

		$item_str = sprintf($itemTpl, $videoArray['MediaId'], $videoArray['ThumbMediaId'], $videoArray['Title'], $videoArray['Description']);

		$xmlTpl = "<xml>
			<ToUserName><![CDATA[%s]]></ToUserName>
			<FromUserName><![CDATA[%s]]></FromUserName>
			<CreateTime>%s</CreateTime>
			<MsgType><![CDATA[video]]></MsgType>
			$item_str
			</xml>";

		$result = sprintf($xmlTpl, $object -> FromUserName, $object -> ToUserName, time());
		return $result;
	}

	//回复图文消息
	private function transmitNews($object, $newsArray) {
		if (!is_array($newsArray)) {
			return;
		}
		$itemTpl = "    <item>
			        <Title><![CDATA[%s]]></Title>
			        <Description><![CDATA[%s]]></Description>
			        <PicUrl><![CDATA[%s]]></PicUrl>
			        <Url><![CDATA[%s]]></Url>
			    </item>
			";
		$item_str = "";
		foreach ($newsArray as $item) {
			$item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);
		}
		$xmlTpl = "<xml>
				<ToUserName><![CDATA[%s]]></ToUserName>
				<FromUserName><![CDATA[%s]]></FromUserName>
				<CreateTime>%s</CreateTime>
				<MsgType><![CDATA[news]]></MsgType>
				<ArticleCount>%s</ArticleCount>
				<Articles>
				$item_str</Articles>
				</xml>";

		$result = sprintf($xmlTpl, $object -> FromUserName, $object -> ToUserName, time(), count($newsArray));
		return $result;
	}

	//回复音乐消息
	private function transmitMusic($object, $musicArray) {
		$itemTpl = "<Music>
				    <Title><![CDATA[%s]]></Title>
				    <Description><![CDATA[%s]]></Description>
				    <MusicUrl><![CDATA[%s]]></MusicUrl>
				    <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
				</Music>";

		$item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']);

		$xmlTpl = "<xml>
			<ToUserName><![CDATA[%s]]></ToUserName>
			<FromUserName><![CDATA[%s]]></FromUserName>
			<CreateTime>%s</CreateTime>
			<MsgType><![CDATA[music]]></MsgType>
			$item_str
			</xml>";

		$result = sprintf($xmlTpl, $object -> FromUserName, $object -> ToUserName, time());
		return $result;
	}

	//回复多客服消息
	private function transmitService($object) {
		$xmlTpl = "<xml>
				<ToUserName><![CDATA[%s]]></ToUserName>
				<FromUserName><![CDATA[%s]]></FromUserName>
				<CreateTime>%s</CreateTime>
				<MsgType><![CDATA[transfer_customer_service]]></MsgType>
				</xml>";
		$result = sprintf($xmlTpl, $object -> FromUserName, $object -> ToUserName, time());
		return $result;
	}

	//日志记录
	private function logger($log_content) {
		if (isset($_SERVER['HTTP_APPNAME'])) {//SAE
			sae_set_display_errors(false);
			sae_debug($log_content);
			sae_set_display_errors(true);
		} else if ($_SERVER['REMOTE_ADDR'] != "127.0.0.1") {//LOCAL
			/*$max_size = 10000;
			 $log_filename = "log.xml";
			 if (file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)) {unlink($log_filename);
			 }
			 file_put_contents($log_filename, date('H:i:s') . " " . $log_content . "\r\n", FILE_APPEND);*/
			error_log(date('H:i:s') . " " . $log_content . "\r\n");
		}
	}

}

/**
 * 获取微信图片
 */
function downloadWeixinFile($url) {
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	curl_setopt($ch, CURLOPT_NOBODY, 0);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$package = curl_exec($ch);
	$httpinfo = curl_getinfo($ch);
	curl_close($ch);
	$imageAll = array_merge(array('header' => $httpinfo), array('body' => $package));
	return $imageAll;
}

/**
 * 保存微信图片
 */
function saveWeixinFile($filename, $filecontent) {
	$local_file = fopen($filename, 'w');
	if (false !== $local_file) {
		if (false !== fwrite($local_file, $filecontent)) {
			fclose($local_file);
		}
	}
}

/**
 * 获取附近的调用
 */
function catchEntitiesFromLocation($entity, $x, $y, $radius) {
	$mapObj = new baiduMapClient();
	$search = $mapObj -> Place_search($entity, $x . "," . $y, $radius);
	$results = $search -> results;
	for ($i = 0; $i < count($results); $i++) {
		$distance = getDistance($x, $y, $results[$i] -> location -> lat, $results[$i] -> location -> lng);
		$shopSortArrays[$distance] = array("Title" => "【" . $results[$i] -> name . "】<" . $distance . "M>" . $results[$i] -> address . (isset($results[$i] -> telephone) ? " " . $results[$i] -> telephone : ""), "Description" => "", "PicUrl" => "", "Url" => "");
	}
	ksort($shopSortArrays);
	//排序
	$shopArray = array();
	foreach ($shopSortArrays as $key => $value) {
		$shopArray[] = array("Title" => $value["Title"], "Description" => $value["Description"], "PicUrl" => $value["PicUrl"], "Url" => $value["Url"], );
		error_log("title=" + $value["Title"] + ",description=" + $value["Description"] + ",pic=" + $value["PicUrl"] + ",url=" + $value["Url"]);
		if (count($shopArray) > 4) {
			break;
		}
	}
	return $shopArray;
}

/**
 * 计算两坐标之间距离
 */
function getDistance($lat_a, $lng_a, $lat_b, $lng_b) {
	//R是地球半径（米）
	$R = 6366000;
	$pk = doubleval(180 / 3.14169);

	$a1 = doubleval($lat_a / $pk);
	$a2 = doubleval($lng_a / $pk);
	$b1 = doubleval($lat_b / $pk);
	$b2 = doubleval($lng_b / $pk);

	$t1 = doubleval(cos($a1) * cos($a2) * cos($b1) * cos($b2));
	$t2 = doubleval(cos($a1) * sin($a2) * cos($b1) * sin($b2));
	$t3 = doubleval(sin($a1) * sin($b1));
	$tt = doubleval(acos($t1 + $t2 + $t3));

	return round($R * $tt);
}

?>